<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ES6语法测试</title>
</head>
<body>
    
<script>

    //javaScript中的基本类型 undefined null Boolean string number
    //模板字符串 替换字符串之间的+ 用``包裹
    // querySelector 是一个在 JavaScript 中用于在文档对象模型（DOM）中选择单个元素的方法。
    // 它是 Document 和 Element 接口的一部分，允许你使用 CSS 选择器语法来查找与指定选择器或选择器组匹配的第一个元素。
    //箭头函数
    function Person(){
  this.age = 0;
 
  setInterval(() => {
    // |this| 指向 person 对象
    this.age++;
 //   console.log(this.age);
  }, 1000);
}
 var person = new Person();

// ES6 允许声明在对象字面量时使用简写语法，来初始化属性变量和函数的定义方法，并且允许在对象属性中进行计算操作：

function getCar(make, model, value) {
  return {
    // 简写变量
    make,  // 等同于 make: make
    model, // 等同于 model: model
    value, // 等同于 value: value
 
    // 属性可以使用表达式计算值
    ['make' + make]: true,
 
    // 忽略 `function` 关键词简写对象函数
    depreciate() {
      this.value -= 2500;
    }
  };
}

//ES6 中允许你对函数参数设置默认值：

 let num = (a,b=4)=>{
    return a+b;
 }
 console.log(num(1));
 
// Spread / Rest 操作符
// Spread / Rest 操作符指的是 ...，具体是 Spread 还是 Rest 需要看上下文语境。
// 当被用于迭代器中时，它是一个 Spread 操作符
//当被用于函数传参时，是一个 Rest 操作符：
function foo(x,y,z) {
    console.log(x,y,z)
}
let arr=[1,2,3];
foo(...arr);

//将数字包装成数组输出
function foo1(...args){
    console.log(args);
}
foo1(1,2,3,4);

//[ ] 对象字面量中使用
let propName = 'myProperty';  
  
// 使用计算属性名  
let obj = {  
  [propName]: 'Hello, world!',  
  ['another' + 'Property']: 42  
};  
  
console.log(obj);  
// 输出: { myProperty: 'Hello, world!', anotherProperty: 42 } 

//ES6 支持二进制和八进制的字面量，通过在数字前面添加 0o 或者0O 即可将其转换为八进制值：

let oValue = 0o10;
console.log(oValue); // 8
 
let bValue = 0b11; // 二进制使用 `0b` 或者 `0B`
console.log(bValue); // 2

// 对象和数组解构
// 解构可以避免在对象赋值时产生中间变量：
function test1(){
    return [1,2,3,4];
}
 let [a,b,c,d]=test1();
 console.log([a,b,c,d]);

 //对象解构
 function test2(){
    return {
        x:1,
        y:2,
        z:3
    }
 }
 let {x,y,z}=test2();
console.log(x,y,z);

//ES6 允许在对象中使用 super 方法：

var parent = {
    p1(){
        console.log('你好，我是父亲');
    }
}

var child ={
   p1(){
    super.p1();
  console.log('你好，我是孩子');
  
   }
}

//要先绑定孩子对象，
Object.setPrototypeOf(child, parent);
child.p1();

// ES6 中有一种十分简洁的方法组装一堆字符串和变量。

// ${ ... } 用来渲染一个变量
// ` 作为分隔符
let user = 'Barret';
console.log(`你好  ${user}`); // Hi Barret!

//for...of 用于遍历一个迭代器，如数组：
let array=['a','b','c'];
array.bc=8;

for (let e of array){
    console.log(e);  
}
//for...in 用来遍历对象中的属性：
let p={
        x:1,
        y:2,
        z:3
    }
for (let e in p){
    console.log(e);
    
}

// Map 和 WeakMap
// ES6 中两种新的数据结构集：Map 和 WeakMap。事实上每个对象都可以看作是一个 Map。
// 一个对象由多个 key-val 对构成，在 Map 中，任何类型都可以作为对象的 key，如：

let myMap=new Map();

let bh="ad";
let bd={};
let ch=()=>{};

myMap.set(bh,"1");
myMap.set(bd,"2");
myMap.set(ch,"3");

console.log(myMap.get(bh));

// ES6 中有 class 语法。值得注意是，这里的 class 不是新的对象继承模型，它只是原型链的语法糖表现形式。
// 函数中使用 static 关键词定义构造函数的的方法和属性：

class Task{
 
    constructor(){
        console.log('constructor');
        
    };

    f1(){
        console.log('f1');
        
    }
}

console.log(typeof Task);

let tast=new Task();
tast.f1();

//类的继承
class Task1 extends Task{
    constructor(){
        super();
        console.log('constructor11');
        
    };
}

let Task11=new Task1();

var sym = Symbol( "some optional description" );
console.log(typeof sym); // symbol

var o = {
    val: 10,
    [ Symbol("random") ]: "I'm a symbol",
};
 
console.log(Object.getOwnPropertyNames(o)); // val

var ar = [11,12,13];
var itr = ar[Symbol.iterator]();
 
  console.log( itr.next());
  console.log( itr.next());
  console.log( itr.next());
   // { value: 11, done: false }
   itr.next(); // { value: 12, done: false }
itr.next(); // { value: 13, done: false }
 
itr.next(); // { value: undefined, done: true }

(function() {
  console.log('这个函数会立即执行！');
})();

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();
 console.log('add',add());
 
add();
add();
let aaaa = add();

console.log('技术器',aaaa);

 
// 计数器为 3
    </script>
</body>
</html>